package com.ssy.lingxi.enhance.serviceimpl.common;

import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.enhance.constant.*;
import com.ssy.lingxi.enhance.entity.*;
import com.ssy.lingxi.enhance.model.vo.ProduceNoticeOrderDetailsVO;
import com.ssy.lingxi.enhance.model.vo.TaskStepVO;
import com.ssy.lingxi.enhance.repository.*;
import com.ssy.lingxi.enhance.service.common.CommonService;
import com.ssy.lingxi.workflow.api.feign.ProcessFeign;
import com.ssy.lingxi.workflow.api.model.vo.request.ExternalProcessQueryVO;
import com.ssy.lingxi.workflow.api.model.vo.request.InternalProcessQueryVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleProcessDefVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 公共部分 - 业务实现层
 * @author fhj
 * @date 2021/07/27
 * @version 2.0.0
 */
@Slf4j
@Service
public class CommonServiceImpl implements CommonService {

    @Resource
    private ProcessFeign processFeign;
    @Resource
    private ProduceNoticeOrderRepository produceNoticeOrderRepository;
    @Resource
    private ProduceNoticeOrderDetailRepository produceNoticeOrderDetailRepository;
    @Resource
    private PNOReceiveDeliverDetailRepository pnoReceiveDeliverDetailRepository;
    @Resource
    private InnerWorkflowRecordRepository innerWorkflowRecordRepository;
    @Resource
    private OuterWorkflowRecordRepository outerWorkflowRecordRepository;

    /**
     * 详情
     * */
    @Override
    public Wrapper<ProduceNoticeOrderDetailsVO> details(Long id, Integer roleType, UserLoginCacheDTO user) {
        //校验
        if(id == null || roleType == null || user == null) {
            return Wrapper.fail(ResponseCode.PT_PARAMETER_VERIFICATION_FAILED);
        }

        //根据ID获取生产通知单详情
        ProduceNoticeOrderDO produceNoticeOrder = produceNoticeOrderRepository.findById(id).orElse(null);
        if(produceNoticeOrder == null) {
            return Wrapper.fail(ResponseCode.ENHANCE_BY_ID_NOT_FOUND_PNO);
        }

        //拷贝
        ProduceNoticeOrderDetailsVO vo = new ProduceNoticeOrderDetailsVO();
        BeanUtils.copyProperties(produceNoticeOrder, vo);

        //定义局部变量：内部状态名称、工作流key、任务ID、会员ID
        String innerStatusName = PNOAllStatusEnum.getMessage(produceNoticeOrder.getStatus());
        String processKey = null;
        String taskId = null;
        Long memberId = null;

        //根据角色类型来赋值局部变量
        if(roleType.equals(RoleTypeEnum.SUPPLIER.getCode())) {
            innerStatusName = PNOSupplierInnerStatusEnum.getMessage(produceNoticeOrder.getSupplierInnerStatus());
            processKey = produceNoticeOrder.getSupplierInnerProcessKey();
            taskId = produceNoticeOrder.getSupplierInnerTaskId();
            memberId = produceNoticeOrder.getSupplierMemberId();
        }else if(roleType.equals(RoleTypeEnum.PROCESS.getCode())) {
            innerStatusName = PNOProcessInnerStatusEnum.getMessage(produceNoticeOrder.getProcessInnerStatus());
            processKey = produceNoticeOrder.getProcessInnerProcessKey();
            taskId = produceNoticeOrder.getProcessInnerTaskId();
            memberId = produceNoticeOrder.getProcessMemberId();
        }

        //封装外部状态名称, 内部状态名称
        vo.setOuterStatusName(PNOOuterStatusEnum.getMessage(vo.getOuterStatus()));
        vo.setInnerStatusName(innerStatusName);

        //根据生产通知单ID获取内部工作流记录集合
        List<InnerWorkflowRecordDO> innerWorkflowRecordList = innerWorkflowRecordRepository.findByProduceNoticeOrderIdAndType(id, roleType);
        vo.setInnerWorkflowRecordsList(innerWorkflowRecordList);

        //根据生产通知单ID获取外部工作流记录集合
        List<OuterWorkflowRecordDO> outerWorkflowRecordsList = outerWorkflowRecordRepository.findByProduceNoticeOrderId(id);
        vo.setOuterWorkflowRecordsList(outerWorkflowRecordsList);

        //根据生产通知单ID获取生产通知单明细
        List<ProduceNoticeOrderDetailDO> details = produceNoticeOrderDetailRepository.findByProduceNoticeOrderId(id);
        vo.setDetails(details);

        //根据生产通知单ID获取生产通知单收发货明细
        List<PNOReceiveDeliverDetailDO> pnoReceiveDeliverDetailDOList = pnoReceiveDeliverDetailRepository.findByProduceNoticeOrderId(id);
        vo.setPnoReceiveDeliverDetailDOList(pnoReceiveDeliverDetailDOList);

        //获取内部工作流程, 调用工作流服务 -> 查询单一的内部流程的定义
        if(!roleType.equals((RoleTypeEnum.PLATFORM.getCode()))) {
            InternalProcessQueryVO internalProcessQueryVO = new InternalProcessQueryVO();
            internalProcessQueryVO.setProcessKey(processKey);
            internalProcessQueryVO.setTaskId(taskId);
            internalProcessQueryVO.setMemberId(memberId);
            Wrapper<SimpleProcessDefVO> innerWrapper = processFeign.findSimpleInternalTaskDefinitions(internalProcessQueryVO);
            if(innerWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                log.error("工作流服务异常:" + innerWrapper.getMessage());
                throw new BusinessException(ResponseCode.ENHANCE_WORKFLOW_ERROR);
            }
            //封装内部工作流程
            List<TaskStepVO> innerTaskList = innerWrapper.getData().getTasks().stream().map(a -> {
                TaskStepVO taskStepVO = new TaskStepVO();
                taskStepVO.setStep(a.getTaskStep());
                taskStepVO.setRoleName(a.getRoleName());
                taskStepVO.setTaskName(a.getTaskName());
                if(innerWrapper.getData().getCurrentStep() == 0 || innerWrapper.getData().getCurrentStep() >= a.getTaskStep()) {
                    taskStepVO.setIsExecute(CommonBooleanEnum.YES.getCode());
                }else {
                    taskStepVO.setIsExecute(CommonBooleanEnum.NO.getCode());
                }
                return taskStepVO;
            }).collect(Collectors.toList());
            vo.setInnerTaskList(innerTaskList);
        }

        //获取外部工作流程, 调用工作流服务 -> 查询单一的外部流程的定义
        ExternalProcessQueryVO externalProcessQueryVO = new ExternalProcessQueryVO();
        externalProcessQueryVO.setProcessKey(produceNoticeOrder.getOuterProcessKey());
        externalProcessQueryVO.setTaskId(produceNoticeOrder.getOuterTaskId());
        externalProcessQueryVO.setRoleId(produceNoticeOrder.getSupplierRoleId());
        externalProcessQueryVO.setSubRoleId(produceNoticeOrder.getProcessRoleId());
        Wrapper<SimpleProcessDefVO> outerWrapper = processFeign.findSimpleExternalTaskDefinitions(externalProcessQueryVO);
        if(outerWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("工作流服务异常:" + outerWrapper.getMessage());
            throw new BusinessException(ResponseCode.ENHANCE_WORKFLOW_ERROR);
        }
        //封装外部工作流程
        List<TaskStepVO> outerTaskList = outerWrapper.getData().getTasks().stream().map(a -> {
            TaskStepVO taskStepVO = new TaskStepVO();
            taskStepVO.setStep(a.getTaskStep());
            taskStepVO.setRoleName(a.getRoleName());
            taskStepVO.setTaskName(a.getTaskName());
            if(outerWrapper.getData().getCurrentStep() == 0 || outerWrapper.getData().getCurrentStep() >= a.getTaskStep()) {
                taskStepVO.setIsExecute(CommonBooleanEnum.YES.getCode());
            }else {
                taskStepVO.setIsExecute(CommonBooleanEnum.NO.getCode());
            }
            return taskStepVO;
        }).collect(Collectors.toList());
        vo.setOuterTaskList(outerTaskList);

        return Wrapper.success(vo);
    }
}
